﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.IO;

namespace PostProcessing
{
    public partial class Form1 : Form
    {
        OpenFileDialog browse;
        Conviction conviccao;
        Generalizer generalizer;

        public Form1()
        {
            InitializeComponent();
            browse = new OpenFileDialog();
            browse.CheckFileExists = true;
            browse.CheckPathExists = true;
            browse.Filter = "Arquivos txt (*.txt)|*.txt|Todos os Arquivos (*.*)|*.*";
            conviccao = new Conviction();
            generalizer = new Generalizer();
        }

        private void buttonArqRegras_Click(object sender, EventArgs e)
        {
            if (browse.ShowDialog() == DialogResult.OK)
            {
                textBoxArqRegras.Text = browse.FileName;
            }
        }

        private void buttonArqDados_Click(object sender, EventArgs e)
        {
            if (browse.ShowDialog() == DialogResult.OK)
            {
                textBoxArqDados.Text = browse.FileName;
            }
        }

        private void buttonConviccao_Click(object sender, EventArgs e)
        {
            if ((textBoxArqRegras.Text != "") && (textBoxArqDados.Text != "") && (textBoxArqSaidaConvic.Text != "") && (textBoxGrauMinimo.Text != ""))
            {
                if (!textBoxArqSaidaConvic.Text.EndsWith(".txt"))
                    textBoxArqSaidaConvic.Text += ".txt";

                barraEstimativa1._setMaxProgressValue(100L, "Gerando Graus de Interesse e Podando Conjunto de Regras.");
                backgroundWorker1.RunWorkerAsync(new string[] { textBoxArqRegras.Text, textBoxArqDados.Text, textBoxArqSaidaConvic.Text, textBoxGrauMinimo.Text});

                textBoxArqRegrasConvic.Text = textBoxArqSaidaConvic.Text.Replace(".txt", "_podado.txt");
            }
            else
                MessageBox.Show("Informe os seguintes itens: Arquivo de Dados, Arquivo de Regras, Nome do Arquivo de Saída e Grau de Interesse Mínimo.");
        }

        private void buttonGeneralizar_Click(object sender, EventArgs e)
        {
            if (generalizer.existeTaxonomias())
            {
                if (textBoxArqDados.Text != "" &&
                    textBoxArqRegrasConvic.Text != "" && textBoxMaxItensAntec.Text != "" &&
                    textBoxConfMinima.Text != "" && textBoxArqSaidaGen.Text != "")
                {
                    if (!textBoxArqSaidaGen.Text.EndsWith(".txt"))
                        textBoxArqSaidaGen.Text += ".txt";

                    if (File.Exists(textBoxArqSaidaGen.Text))
                        File.Delete(textBoxArqSaidaGen.Text);

                    barraEstimativa1._setMaxProgressValue(100L, "Generalizando conjunto de regras.");
                    backgroundWorker2.RunWorkerAsync(new object[] {textBoxArqDados.Text,
                                                                    textBoxArqRegrasConvic.Text,
                                                                    int.Parse(textBoxMaxItensAntec.Text),
                                                                    int.Parse(textBoxConfMinima.Text),
                                                                    textBoxArqSaidaGen.Text});
                }
                else
                    MessageBox.Show("Informe os seguintes itens: Arquivo de Dados, Arquivo de Regras com Graus de Interesse, " +
                                        "Máximo de Itens por Antecedente, Confiança Mínima e Arquivo de saída.");
            }
            else
                MessageBox.Show("Impossível generalizar sem nenhuma taxonomia. Por favor crie algumas taxonomias ou abra um arquivo de taxonomias.");
        }

        private void buttonAddFilho_Click(object sender, EventArgs e)
        {
            try
            {
                //Adiciona um filho ao nó cabeça ou a um determinado pai se este foi informado.
                if ((textBoxFilho.Text != "") && (textBoxTaxonomia.Text != ""))
                {
                    if (textBoxRepFn.Text != "")
                    {
                        if (textBoxRepIn.Text == "")
                            textBoxRepIn.Text = "1";

                        int inicial = int.Parse(textBoxRepIn.Text);
                        int final = int.Parse(textBoxRepFn.Text);

                        if (inicial < final)
                        {
                            for (int i = inicial; i <= final; i++)
                            {
                                generalizer.addNode(textBoxTaxonomia.Text.ToLower(), textBoxPai.Text.ToLower(), textBoxFilho.Text.ToLower() + i.ToString());
                            }
                        }
                    }
                    else
                        generalizer.addNode(textBoxTaxonomia.Text.ToLower(), textBoxPai.Text.ToLower(), textBoxFilho.Text.ToLower());

                    textBoxRepIn.Text = "";
                    textBoxRepFn.Text = "";
                    atualizaTreeView();
                }
                else
                    MessageBox.Show("É necessário sempre preencher o campo Taxonomia e o Filho.");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void buttonAbrir_Click(object sender, EventArgs e)
        {
            OpenFileDialog openFileDialog;

            using (openFileDialog = new OpenFileDialog())
            {
                openFileDialog.DefaultExt = "tax";
                openFileDialog.Filter = "Arquivos TAX (*.tax)|*.tax";

                if (openFileDialog.ShowDialog() == DialogResult.OK)
                {
                    textBoxArqTax.Text = openFileDialog.FileName;

                    generalizer.openBinaryFile(openFileDialog.FileName);
                }
            }

            atualizaTreeView();
        }

        private void buttonSalvar_Click(object sender, EventArgs e)
        {
            SaveFileDialog saveFileDialog;

            using (saveFileDialog = new SaveFileDialog())
            {
                saveFileDialog.DefaultExt = "tax";
                saveFileDialog.Filter = "Arquivos TAX (*.tax)|*.tax";

                if (saveFileDialog.ShowDialog() == DialogResult.OK)
                {
                    generalizer.saveTaxsToBinaryFile(saveFileDialog.FileName);
                    textBoxArqTax.Text = saveFileDialog.FileName;
                }
            }
        }

        private void buttonArqRegrasConvic_Click(object sender, EventArgs e)
        {
            if (browse.ShowDialog() == DialogResult.OK)
            {
                textBoxArqRegrasConvic.Text = browse.FileName;
            }
        }

        private void buttonAddTaxonomia_Click(object sender, EventArgs e)
        {
            try
            {
                //Adicionar nova taxonomia.
                if (textBoxTaxonomia.Text != "")
                {
                    generalizer.addTaxonomia(textBoxTaxonomia.Text.ToLower());

                    atualizaTreeView();
                }
                else
                    MessageBox.Show("Por favor informe o nome da taxonomia que será adicionada.");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void atualizaTreeView()
        {
            treeViewTaxonomias.Nodes.Clear();
            treeViewTaxonomias.Nodes.Add(generalizer.gerarTreeView());
            treeViewTaxonomias.Nodes[0].Expand();
        }

        private void buttonRemTaxonomia_Click(object sender, EventArgs e)
        {
            try
            {
                if (textBoxTaxonomia.Text != "")
                {
                    if (MessageBox.Show("Tem certeza que deseja remover esta taxonomia?", "ATENÇÃO", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        generalizer.removerTaxonomia(textBoxTaxonomia.Text.ToLower());
                        atualizaTreeView();
                    }
                }
                else
                    MessageBox.Show("Por favor informe o nome da taxonomia que será removida.");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void buttonRemPai_Click(object sender, EventArgs e)
        {
            try
            {
                if (textBoxTaxonomia.Text != "" && textBoxPai.Text != "")
                {
                    if (MessageBox.Show("Tem certeza que deseja remover este pai?", "ATENÇÃO", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        generalizer.removeNode(textBoxTaxonomia.Text.ToLower(), textBoxPai.Text.ToLower());
                        atualizaTreeView();
                    }
                }
                else
                    MessageBox.Show("Por favor informe o nome da taxonomia e o nome do pai que será removido desta taxonomia.");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void buttonRemFilho_Click(object sender, EventArgs e)
        {
            try
            {
                if (textBoxTaxonomia.Text != "" && textBoxFilho.Text != "")
                {
                    if (MessageBox.Show("Tem certeza que deseja remover este(s) filho(s)?", "ATENÇÃO", MessageBoxButtons.YesNo) == DialogResult.Yes)
                    {
                        if (textBoxRepFn.Text != "")
                        {
                            if (textBoxRepIn.Text == "")
                                textBoxRepIn.Text = "1";

                            int inicial = int.Parse(textBoxRepIn.Text);
                            int final = int.Parse(textBoxRepFn.Text);

                            if (inicial < final)
                            {
                                for (int i = inicial; i <= final; i++)
                                {
                                    generalizer.removeNode(textBoxTaxonomia.Text.ToLower(), textBoxFilho.Text.ToLower() + i.ToString());
                                }
                            }
                            textBoxRepIn.Text = "";
                            textBoxRepFn.Text = "";
                        }
                        else
                            generalizer.removeNode(textBoxTaxonomia.Text.ToLower(), textBoxFilho.Text.ToLower());

                        atualizaTreeView();
                    }
                }
                else
                    MessageBox.Show("Por favor informe o nome da taxonomia e o nome do filho que será removido desta taxonomia.");
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void treeViewTaxonomias_NodeMouseClick(object sender, TreeNodeMouseClickEventArgs e)
        {
            if (e.Node.Text != "Taxonomias")
            {
                //Se for um nome de taxonomia...
                if (generalizer.indiceTaxonomia(e.Node.Text) != -1)
                {
                    textBoxTaxonomia.Text = e.Node.Text;
                    textBoxFilho.Text = "";
                    textBoxPai.Text = "";
                }
                else if (e.Node.Nodes.Count == 0)  //Se não tem filhos...
                {
                    textBoxTaxonomia.Text = generalizer.encontraTax(e.Node.Text);

                    if (e.Button == MouseButtons.Left)
                    {
                        if (generalizer.indiceTaxonomia(e.Node.Parent.Text) == -1)
                            textBoxPai.Text = e.Node.Parent.Text;
                        else
                            textBoxPai.Text = "";

                        textBoxFilho.Text = e.Node.Text;
                    }
                    else if (e.Button == MouseButtons.Right)
                    {
                        textBoxPai.Text = e.Node.Text;
                        textBoxFilho.Text = "";
                    }
                }
                else
                {
                    textBoxTaxonomia.Text = generalizer.encontraTax(e.Node.Text);

                    textBoxPai.Text = e.Node.Text;
                    textBoxFilho.Text = "";
                }
            }
            else
            {
                textBoxTaxonomia.Text = "";
                textBoxFilho.Text = "";
                textBoxPai.Text = "";
            }
        }

        private void backgroundWorker1_DoWork(object sender, DoWorkEventArgs e)
        {
            conviccao.gerarGrausDeInteresse(((string[])e.Argument)[0], ((string[])e.Argument)[1], ((string[])e.Argument)[2], (BackgroundWorker)sender);
            e.Result = conviccao.podarConjuntoDeRegras(((string[])e.Argument)[2], float.Parse(((string[])e.Argument)[3]), (BackgroundWorker)sender);
        }

        private void backgroundWorker_ProgressChanged(object sender, ProgressChangedEventArgs e)
        {
            barraEstimativa1._setProgressValue(e.ProgressPercentage);
        }

        private void backgroundWorker1_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            MessageBox.Show("Graus de interesse gerados com sucesso. " +
                                    ((int)e.Result).ToString() + " regras podadas por estarem com um baixo grau de interesse.");
        }

        private void backgroundWorker2_DoWork(object sender, DoWorkEventArgs e)
        {
            object[] argumentos = (object[]) e.Argument;

            e.Result = generalizer.generalizarConjuntoRegras((string)argumentos[0],
                                                                    (string)argumentos[1],
                                                                    (int)argumentos[2],
                                                                    (int)argumentos[3],
                                                                    (string)argumentos[4],
                                                                    (BackgroundWorker)sender);
        }

        private void backgroundWorker2_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            Log log = (Log)e.Result;

            labelQtdGenInuteis.Text = log.regrasGenInuteis.Count.ToString();
            labelQtdRegrasBaixaConf.Text = log.regrasGenConfBaixa.Count.ToString();
            labelQtdRegrasGenColuna.Text = log.regrasGeneralizadas.Count.ToString();
            labelQtdRegrasGenLinha.Text = log.regrasGenEmLinha.Count.ToString();
            labelQtdGenUteis.Text = log.regrasGenRealmenteUteis.Count.ToString();

            log.salvarArquivo("log.txt");

            MessageBox.Show("Generalização concluída com sucesso.");
        }
    }
}
